package com.tansun.easycare.rule.ruletest.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.RecursiveAction;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.DVConstraint;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFDataValidationConstraint;
import org.apache.poi.xssf.usermodel.XSSFDataValidationHelper;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.tansun.easycare.core.config.Global;
import com.tansun.easycare.rule.common.Constant;
import com.tansun.easycare.rule.common.ResMessage;
import com.tansun.easycare.rule.common.enums.ContentTypeEnum;
import com.tansun.easycare.rule.common.service.DataBomService;
import com.tansun.easycare.rule.common.service.RuleRefCommService;
import com.tansun.easycare.rule.common.service.impl.RuleBaseServiceImpl;
import com.tansun.easycare.rule.datamodel.entity.RuleDataDomain;
import com.tansun.easycare.rule.exception.BizException;
import com.tansun.easycare.rule.referencedata.entity.RuleReferenceData;
import com.tansun.easycare.rule.referencedata.model.RuleDataModelVO;
import com.tansun.easycare.rule.referencedata.service.RuleReferenceDataService;
import com.tansun.easycare.rule.rulemange.entity.RuleManage;
import com.tansun.easycare.rule.rulemange.service.RuleManageService;
import com.tansun.easycare.rule.ruletest.dao.RuleTestDao;
import com.tansun.easycare.rule.ruletest.entity.RuleTest;
import com.tansun.easycare.rule.ruletest.model.RuleBatchResult;
import com.tansun.easycare.rule.ruletest.model.RuleTestMap;
import com.tansun.easycare.rule.ruletest.service.RuleBatchTestService;
import com.tansun.easycare.rule.ruletest.service.RuleTestService;
import com.tansun.easycare.rule.ruleversion.service.RuleVersioninfoService;
import com.tansun.easycare.rule.utils.BigExcelUtils;
import com.tansun.easycare.rule.utils.ExcelConstant;
import com.tansun.easycare.rule.utils.MapSheetContentsHandler;
import com.tansun.rule.common.RuleModelTypeEnum;
import com.tansun.rule.utils.LoggerManager;
import com.tansun.rule.utils.MClass;
import com.tansun.rule.utils.MField;


@Service("RuleBatchTestService")
public class RuleBatchTestServiceImpl extends RuleBaseServiceImpl<RuleTestDao, RuleTest> implements RuleBatchTestService {

    @Autowired
    private RuleReferenceDataService ruleReferenceDataService;
    @Autowired
    private DataBomService dataBomService;

    @Autowired
    private RuleTestService ruleTestService;

	@Autowired
	private RuleManageService ruleManageService;

    @Autowired
    private RuleRefCommService ruleRefCommService;
    @Autowired
    private RuleVersioninfoService ruleVersioninfoService;

    private SimpleDateFormat spf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public void createBatchTest(RuleTest ruleTest) throws BizException {
        ruleTest.setTestType("1");
        ruleTest.setStatus("12");
        this.save(ruleTest);

    }

    @Override
    public String[] createExcelTemp(String projectCode, RuleTest ruleTest) throws BizException {
        String downRoot = Global.getConfig("file.uploadRoot");

        String[] result = new String[2];

        String downNameString = downRoot + File.separator + projectCode + File.separator
                + RuleModelTypeEnum.getRuleModelTypeEnum(ruleTest.getModelType());

        String fileName = RuleModelTypeEnum.getName(ruleTest.getModelType());
        fileName = fileName + "_" + ruleTest.getRuleName();
        fileName = fileName + "_" + ruleTest.getVersion();
        try {
            fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
        } catch (UnsupportedEncodingException e1) {
            LoggerManager.error("", e1, this.getClass());
        }
        File tmpFile = new File(downNameString);
        if (!tmpFile.exists()) {
            tmpFile.mkdirs();
        }

        String tmpPath = downNameString + File.separator + fileName + ".xlsx";
        result[0] = tmpPath;
        result[1] = fileName;
        File file = new File(tmpPath);
        //TODO 同一个规则版本删除后新增不生成新excle
        /*if (file.exists()) {

            return result;
        }*/
        List<String> list = new ArrayList<String>();

        JSONObject json = new JSONObject();
        List<Object> toplist = new ArrayList<Object>();
        toplist.add(ExcelConstant.TYPE_CELL + RuleModelTypeEnum.getName(ruleTest.getModelType()));

        toplist.add(ExcelConstant.MODEL_CELL + ruleTest.getRuleName());
        toplist.add(ExcelConstant.VERSION_CELL + ruleTest.getVersion());

        toplist.add(ExcelConstant.DATA_CELL + ruleTest.getId());
        json.put(ExcelConstant.R, toplist);
        list.add("");

        json.put(ExcelConstant.R1, list);
        List<Object> list2 = new ArrayList<Object>();
        list2.add("对象");
        json.put(ExcelConstant.R2, list2);
        List<Object> list3 = new ArrayList<Object>();
        list3.add("属性");
        json.put(ExcelConstant.R3, list3);

        int countAttr = 0;

        RuleReferenceData referenceData = new RuleReferenceData();
        referenceData.setCode(ruleTest.getModelCode());
        referenceData.setModelType(ruleTest.getModelType());
        referenceData.setVersion(ruleTest.getVersion());
        referenceData.setContentType(ContentTypeEnum.in.code);
        referenceData.setProjectCode(ruleTest.getProjectCode());
        List<RuleDataModelVO> dataModels = this.findReferenceData(referenceData);
        Map<String, RuleReferenceData> paramMap = new HashMap<String, RuleReferenceData>();
        for (RuleDataModelVO ruleDataModelVO : dataModels) {
        	for(RuleReferenceData ref:ruleDataModelVO.getAttrList()) {
        		paramMap.put(ruleDataModelVO.getClassName()+ref.getNamecn(),ref);
        	}
		}
        Map<Integer, RuleReferenceData> map = new HashMap<Integer, RuleReferenceData>();
        for (RuleDataModelVO dm : dataModels) {
            if (dm.getAttrList().size() > 0 && dm.getAttrList().get(0) != null) {
            	int size = 0;
                for (Entry<String ,RuleReferenceData> entry : paramMap.entrySet()) {
                	if(!dm.getClassName().equals(entry.getValue().getClassName())) 
                		continue;
                	if(list3.contains(entry.getValue().getClassNamecn()+"."+entry.getValue().getNamecn()))
                		continue;
                	list3.add(entry.getValue().getClassNamecn()+"."+entry.getValue().getNamecn());
                	map.put(countAttr, entry.getValue());
                    countAttr++;
                    size++;
        		}
                list2.add(dm.getClassNamecn() + "##" + size); 
            }
        }
        if (countAttr > 1) {
            list.add("赋值##" + countAttr);
        } else {
            list.add("赋值");
        }

        XSSFWorkbook wb = new XSSFWorkbook();
        Sheet sheet = wb.createSheet("new Sheet");
        CellStyle style = wb.createCellStyle();
        style.setAlignment(CellStyle.ALIGN_CENTER); // 创建一个居中格式
        writeHeadText(json.getJSONArray(ExcelConstant.R), style, sheet.createRow(0), sheet);
        writeHeadText(json.getJSONArray(ExcelConstant.R1), style, sheet.createRow(1), sheet);

        writeHeadText(json.getJSONArray(ExcelConstant.R2), style, sheet.createRow(2), sheet);

        writeHeadText(json.getJSONArray(ExcelConstant.R3), style, sheet.createRow(3), sheet);
        if (countAttr >= 1) {
            for (int i = 1; i <= countAttr; i++) {
                addValidation(projectCode, sheet, i, map.get(i-1));
            }
        }
        try {
            FileOutputStream fout = new FileOutputStream(tmpPath);
            wb.write(fout);
            fout.close();
        } catch (Exception e) {
            //e.printStackTrace();
            LoggerManager.error("", e, this.getClass());
        }
        return result;

    }

    public static void writeHeadText(List<Object> getList, CellStyle style, Row row, Sheet sheet) {
        int preLength = 0;
        for (int i = 0; i < getList.size(); i++) {
            Cell cell = row.createCell((short) i + preLength);
            cell.setCellValue(getValue(getList.get(i).toString()));
            int lastColIndex = cell.getColumnIndex() + Integer.valueOf(getColSpan(getList.get(i).toString())) - 1;

            cell.setCellStyle(style);
            if ((cell.getColumnIndex()) < lastColIndex)
                sheet.addMergedRegion(new CellRangeAddress(cell.getRowIndex(), cell.getRowIndex(), cell.getColumnIndex(), lastColIndex));

            preLength = preLength + Integer.valueOf(getColSpan(getList.get(i).toString())) - 1;
        }
    }

    private static String getValue(String linStr) {
        String reg = "(.*?(\\w*))\\#\\#(.*?(\\w*)).*?";
        if (linStr.matches(reg)) {
            Pattern pattern = Pattern.compile(reg);
            Matcher matcher = pattern.matcher(linStr);
            String group = new String();
            while (matcher.find()) {
                group = matcher.group(1);
                return group;
            }
        }
        return linStr;
    }

    private static String getColSpan(String lineStr) {
        String reg = ".*?\\#\\#(.*?(\\d*)).*?";
        if (lineStr.matches(reg)) {
            Pattern pattern = Pattern.compile(reg);
            Matcher matcher = pattern.matcher(lineStr);
            String group = new String();
            if (matcher.find()) {
                group = matcher.group(1);
                return group;
            }
        }
        return "1";
    }

    public void addValidation(String projectCode, Sheet sheet, int colNum, RuleReferenceData ab) throws BizException {

        int valType = 0;
        String items = new String();
        if (StringUtils.isNotBlank(ab.getDomainStr())) {
            items = ab.getDomainStr();
            String  dmStr = StringUtils.substring(items, 0,items.length() - 1);
            dmStr = dmStr +", -]";
            items = dmStr;
            valType = 0;
        } else if (ab.getDataType().equals("Long")) {
            if (StringUtils.isNotBlank(ab.getDomain())) {
                items = ab.getDomain();
                String  spStr =StringUtils.substring(items, 1,items.length() - 1);
                String[] args =   spStr.split(",");
                if (args !=null && args.length==1) {
                		 spStr = spStr+"9999999999";
                		 items = "["+spStr+"]";
                }
            } else {
                items = "[-999,9999999999]";  //by yangpingxia，2018.12.11修改，添加负数输入，扩大输入值范围
            }
            valType = 1;
        } else if (ab.getDataType().equals("Double")) {
            if (StringUtils.isNotBlank(ab.getDomain())) {
                items = ab.getDomain();
                String  spStr =StringUtils.substring(items, 1,items.length() - 1);
                String[] args =   spStr.split(",");
                if (args !=null && args.length==1) {
                		 spStr = spStr+"9999999999";
                		 items = "["+spStr+"]";
                }                
            } else {
                items = "[-999,9999999999]";   //2018.12.11修改，添加负数输入，扩大输入值范围
            }

            valType = 2;
        }
        if (items.length() > 2) {
            items = items.substring(1, items.length() - 1);
            addValidation(items.split(","), sheet, colNum, valType);  
        }

    }


    /**
     * @param valType 0 数组 1 整形 2 浮点
     */
    public static void addValidation(String[] listStr, Sheet sheet, int rowNum, int valType) {
    	if(listStr.length<=1) {  //2018.1203添加，遇空继续
    		return;
    	}
    	
        // DataValidationHelper helper = sheet..getDataValidationHelper();

        CellRangeAddressList regions = new CellRangeAddressList(4, ExcelConstant.ROW_VALIDATION_NUM, rowNum, rowNum);
        DataValidationHelper help = new XSSFDataValidationHelper((XSSFSheet)sheet);
        // 生成下拉框内容
        XSSFDataValidationConstraint constraint = null;
        switch (valType) {
            case 1:
                constraint = (XSSFDataValidationConstraint) help.createNumericConstraint(DVConstraint.ValidationType.INTEGER, DVConstraint.OperatorType.BETWEEN, StringUtils.isEmpty(listStr[0]) || listStr[0].equals("") ? "-999"
                        : listStr[0], StringUtils.isEmpty(listStr[1]) || listStr[1].equals("") ? "9999999" : listStr[1]);
                break;
            case 2:
                constraint = (XSSFDataValidationConstraint) help.createNumericConstraint(DVConstraint.ValidationType.DECIMAL, DVConstraint.OperatorType.BETWEEN, StringUtils.isEmpty(listStr[0]) || listStr[0].equals("") ? "-999"
                        : listStr[0], StringUtils.isEmpty(listStr[1]) || listStr[1].equals("") ? "9999999" : listStr[1]);
                break;
            default:
                constraint = (XSSFDataValidationConstraint) help.createExplicitListConstraint(listStr);
                break;
        }

        // 绑定下拉框和作用区域
        DataValidation data_validation = help.createValidation(constraint, regions);
        // 对sheet页生效
        sheet.addValidationData(data_validation);

    }

    @Override
    public ResMessage add(String projectCode, String id, InputStream input, String suffix) throws BizException {
    	ResMessage res = new ResMessage();
        RuleTest ruleTest = this.get(id);
        
        String uploadRoot = Global.getConfig("file.uploadRoot");
        String uploadPath = uploadRoot + "/" + projectCode + ruleTest.getBaseUpdatePath();
        String tempPath = uploadPath + File.separator + ruleTest.getId() + suffix;
        File f = new File(uploadPath);
        // 创建文件夹
        if (!f.exists()) {
            f.mkdirs();
        }
        
        try {
        	FileUtils.copyInputStreamToFile(input, new File(tempPath));
        	
            RuleTest batchTest2 = null;
            if (".xls".equals(suffix)) {
            	Workbook wb = new HSSFWorkbook(new FileInputStream(tempPath));
            	Sheet sheet = wb.getSheetAt(0);
              	batchTest2 = getBatchTest(sheet);
                //存在额外数据不能检查
//              res = checkoutData(projectCode, ruleTest, sheet);
//              String succs = res.getCode();
//              if (succs != null && !"success".equals(succs)) {
//                  return res;
//              }
            } else {
                MapSheetContentsHandler handler = new MapSheetContentsHandler(null,null,true);
                BigExcelUtils.readExcel(tempPath, handler);
            	batchTest2 = handler.getHeadInfo();
            }

          if (!id.equals(batchTest2.getId())) {
              throw new BizException("E-100002");
          }
        } catch (Exception e) {
            LoggerManager.error("", e, this.getClass());
            throw new BizException(e, "");
        }

        return this.updateBatchTest(ruleTest);

    }


    public List<RuleDataModelVO> findReferenceData(RuleReferenceData referenceData) throws BizException {

        List<RuleDataModelVO> result = new ArrayList<>();

        RuleDataModelVO ruleDataModelVO = null;
        List<RuleReferenceData> list = new ArrayList<>();
        String projectCode = referenceData.getProjectCode();
        String code = referenceData.getCode();
        String version = referenceData.getVersion();
        Collection<RuleReferenceData> refList = new ArrayList<RuleReferenceData>();
		RuleManage  ruleInfo   = new   RuleManage();
		ruleInfo.setCode(code);
		ruleInfo.setVersion(version);
		ruleInfo.setProjectCode(projectCode);
		List<RuleManage> rmlist =this.ruleManageService.findList(ruleInfo);
		if (rmlist == null || rmlist.size()==0){
			throw  new  BizException("E-000600");
		}
        ruleReferenceDataService.findFuncReferenceDataList(ruleInfo, list,referenceData.getContentType());
        if (RuleModelTypeEnum.RuleFlow.code.equals(referenceData.getModelType())
        		||RuleModelTypeEnum.StrategyFlow.code.equals(referenceData.getModelType())) {
            list = this.ruleRefCommService.findRuleFlowReferenceData(projectCode, code, version, null,referenceData.getContentType());
            Collection<RuleReferenceData>  refdatas = this.ruleReferenceDataService.reDataModeRef(list);
            refList.addAll(refdatas);
            
        } else if (RuleModelTypeEnum.ExecutionBlock.code.equals(referenceData.getModelType())) {
            list = this.ruleRefCommService.findExcBlockRefData(projectCode, code, version);
            Collection<RuleReferenceData>  refdatas = this.ruleReferenceDataService.reDataModeRef(list);
            refList.addAll(refdatas);
        } else {
            this.ruleReferenceDataService.findReferenceDataList(projectCode,code,referenceData.getModelType(),version,null,list,null);
            Collection<RuleReferenceData>  refdatas = this.ruleReferenceDataService.reDataModeRef(list);
            refList.addAll(refdatas);
//            if (RuleModelTypeEnum.DecisionTree.code.equals(referenceData.getModelType())) {
//            	Map<String,String> vMap  = new  HashMap<String,String>();
//            	vMap.put("projectCode", projectCode);
//            	vMap.put("code", code);
//            	List<String>  strList = this.ruleVersioninfoService.findRuleRefeCodes(vMap);
//            	if (strList !=null && strList.size()>0) {
//	            	Map<String,Object>  oMap  = new  HashMap<>();
//	            	oMap.put("projectCode", projectCode);
//	            	oMap.put("refeList", strList);
//	            	List<RuleReferenceData> rdList =this.ruleReferenceDataService.findModelReferenceList(oMap);
//	            	refList.addAll(rdList);
//            	}
//            }
        }  
        Map<String, RuleDataModelVO> map = new HashMap<String, RuleDataModelVO>();


        for (RuleReferenceData refData : refList) {
            ruleDataModelVO = map.get(refData.getClassName());
            if (ruleDataModelVO == null) {
                ruleDataModelVO = new RuleDataModelVO();
                ruleDataModelVO.setAttrList(new ArrayList<RuleReferenceData>());

                ruleDataModelVO.setClassName(refData.getClassName());
                ruleDataModelVO.setClassNamecn(refData.getClassNamecn());
                ruleDataModelVO.setParamType(refData.getContentType());
                map.put(refData.getClassName(), ruleDataModelVO);
                result.add(ruleDataModelVO);
            }

            ruleDataModelVO.getAttrList().add(refData);

        }
        return result;

    }

    private RuleTest getBatchTest(Sheet sheet) {
        RuleTest batchTest = new RuleTest();
        List<Object> toplist = new ArrayList<Object>();
        Row row = sheet.getRow(0);
        for (int i = 0; i < row.getLastCellNum(); i++) {//获取测试规则所属信息，包括：组件类型，测试模型，版本号，测试编号。
            Cell cell = row.getCell(i);

            if ((StringUtils.isEmpty(cell.getStringCellValue()) || cell.getStringCellValue().equals(""))) {

            } else {
                toplist.add(cell.getStringCellValue());
            }
        }
        for (Object s : toplist) {
            if (s.toString().indexOf(ExcelConstant.TYPE_CELL) >= 0) {
                RuleModelTypeEnum typeEnum = RuleModelTypeEnum.getRuleModelTypeEnumByName(s.toString().replace(ExcelConstant.TYPE_CELL, "").trim());
                if (typeEnum != null)
                    batchTest.setModelType(typeEnum.code);
            }
            if (s.toString().indexOf(ExcelConstant.MODEL_CELL) >= 0)
                batchTest.setRuleName(s.toString().replace(ExcelConstant.MODEL_CELL, "").trim());

            if (s.toString().indexOf(ExcelConstant.VERSION_CELL) >= 0)
                batchTest.setVersion(s.toString().replace(ExcelConstant.VERSION_CELL, "").trim());
            if (s.toString().indexOf(ExcelConstant.DATA_CELL) >= 0)
                batchTest.setId(s.toString().replace(ExcelConstant.DATA_CELL, "").trim());
        }

        return batchTest;

    }

    private ResMessage checkoutData(String projectCode, RuleTest batchTest, Sheet sheet) throws Exception {
        ResMessage resMessage = new ResMessage("success", "");
        if (StringUtils.isBlank(batchTest.getModelType())) {
            resMessage.setMsg(resMessage.getMsg() + "<div>规则类型不能为空！</div>");
        }
        if (StringUtils.isBlank(batchTest.getModelCode())) {
            resMessage.setMsg(resMessage.getMsg() + "<div>规则模型不能为空！</div>");
        }
        if (StringUtils.isBlank(batchTest.getVersion())) {
            resMessage.setMsg(resMessage.getMsg() + "<div>规则版本不能为空！</div>");
        }

        String type = batchTest.getModelType();


        List<RuleReferenceData> inputList = new ArrayList();
//        RuleReferenceData referenceData = new RuleReferenceData();
//        referenceData.setCode(batchTest.getModelCode());
//        referenceData.setVersion(batchTest.getVersion());
//        referenceData.setModelType(type);
//        referenceData.setContentType(ContentTypeEnum.in.code);
//        inputList.addAll(ruleReferenceDataService.findReferenceDataList(referenceData));
//        
        inputList = this.ruleRefCommService.findRuleFlowReferenceData(projectCode, batchTest.getModelCode(), batchTest.getVersion(), null,ContentTypeEnum.in.code);

        if (inputList == null || inputList.size() == 0) {
            resMessage.setMsg(resMessage.getMsg() + "<div>模型文件不存在，请检查该上传文件第一行信息！</div>");
            return resMessage;
        }

        // 检测r3数据合法
        if (checkOutR3(sheet, inputList, resMessage) == false) {
            return resMessage;
        }

        // 数据检测，为空，数据类型等
        checkOutInput(sheet, inputList, resMessage);

        return resMessage;
    }


    // 检测r3数据合法
    private boolean checkOutR3(Sheet sheet, List<RuleReferenceData> thendms, ResMessage res) {
        boolean flag_ = true;
        Map<String, String> atrrNameZhcnMap = AtrrNameZhcnMap(thendms);
        Row row = sheet.getRow(3);
        for (int i = 1; i < row.getLastCellNum(); i++) {
            boolean flag = false;
            for (Map.Entry<String, String> entry : atrrNameZhcnMap.entrySet()) {
                if (StringUtils.isEmpty(row.getCell(i).getStringCellValue())) {
                    flag = true;
                    continue;
                }
                if (isMappingAtrrNameZhcn(entry.getKey(), row.getCell(i).getStringCellValue(), atrrNameZhcnMap)) {
                    flag = true;
                }
            }
            flag_ = flag;
            if (!flag) {
                res.setCode("fail");
                res.setMsg(res.getMsg() + "<div>第4行第" + i + "列属性名[" + row.getCell(i).getStringCellValue() + "]不存在！</div>");
            }
        }
        return flag_;
    }


    public void checkOutInput(Sheet sheet, List<RuleReferenceData> dms, ResMessage resMessage) {
        Map<String, List<Object>> inputXmls = getInputXml(sheet);
        for (int i = 0; (i < ExcelConstant.ROW_VALIDATION_NUM) && (i <= sheet.getLastRowNum() - 4); i++) {
            int kk = i + 5;
            for (RuleReferenceData dm : dms) {
                if (inputXmls.containsKey(dm.getNamecn())) {
                    if (dm.getDataType().equals(Constant.DATAMODEL_ATTRIBUTE_TYPE_LONG) || dm.getDataType().equals(Constant.DATAMODEL_ATTRIBUTE_TYPE_INTEGER)
                            || dm.getDataType().equals(Constant.DATAMODEL_ATTRIBUTE_TYPE_DOUBLE)) {

                        if (StringUtils.isNotBlank(dm.getDomain()) && !checkDomain(inputXmls.get(dm.getNamecn()).get(i), dm.getDomain())) {
                            resMessage.setCode("fail");
                            resMessage.setMsg(resMessage.getMsg() + "<div>属性名[" + dm.getNamecn() + "]下第" + kk + "行数据为非法数字或不允许为空！</div>");
                        }
                    } else if (StringUtils.isNotBlank(dm.getDomainStr())) {
                        if (dm.getDomainStr().indexOf((inputXmls.get(dm.getNamecn()).get(i)).toString()) < 0) {
                            resMessage.setCode("fail");
                            resMessage.setMsg(resMessage.getMsg() + "<div>属性名[" + dm.getNamecn() + "]下第" + kk + "行数据不包含在允许范围内！</div>");
                        }
                    }
                }

            }
        }
    }


    private Map<String, String> AtrrNameZhcnMap(List<RuleReferenceData> thendms) {
        Map<String, String> atrrNameZhcnMap = new HashMap<String, String>();
        for (RuleReferenceData dm : thendms) {

            atrrNameZhcnMap.put(dm.getClassName()+"."+dm.getNameen(), dm.getClassNamecn()+"."+dm.getNamecn());

        }
        return atrrNameZhcnMap;
    }

    private boolean isMappingAtrrNameZhcn(String name, String Zhacn, Map<String, String> atrrNameZhcnMap) {
        if (atrrNameZhcnMap.containsKey(name)) {
            if (atrrNameZhcnMap.get(name).equals(Zhacn)) {
                return true;
            }
        }
        return false;
    }

    private Map<String, List<Object>> getInputXml(Sheet sheet) {
        Row row = sheet.getRow(3);
        Map<String, List<Object>> inputXml = new HashMap<String, List<Object>>();
        for (int i = 1; i < row.getLastCellNum(); i++) {
            if (StringUtils.isEmpty(row.getCell(i).getRichStringCellValue().toString()))
                continue;
            List<Object> list = getInputVals(sheet, i);
            if(list==null || list.size()==0)
            	continue;
            String key = row.getCell(i).getRichStringCellValue().toString();  //by wangyanghui 2018.12.13，去除同变量重复赋值存在 
            if(inputXml.containsKey(key)) {
            	continue;
            }
            inputXml.put(key, list);
        }
        return inputXml;
    }


    private List<Object> getInputVals(Sheet sheet, int colNum) {
        List<Object> getInputVals = new ArrayList<Object>();
        for (int i = 4; (i <= ExcelConstant.ROW_VALIDATION_NUM + 4) && (i <= sheet.getLastRowNum()); i++) {
            Cell cell = sheet.getRow(i).getCell(colNum);
            if (cell == null) {
              getInputVals.add("");
            } else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
                getInputVals.add(cell.getNumericCellValue());
            } else if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
                getInputVals.add(cell.getStringCellValue());
            } else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
                getInputVals.add(cell.getCellFormula());
            } else if (cell.getCellType() == Cell.CELL_TYPE_BLANK) {
                getInputVals.add("");
            } else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
                getInputVals.add(cell.getBooleanCellValue());
            } else if (cell.getCellType() == Cell.CELL_TYPE_ERROR) {
                getInputVals.add("");
            }
        }
        return getInputVals;
    }

    public boolean checkDomain(Object val, String domain) {
        if (StringUtils.isNumericSpace(val.toString())) {
            return false;
        }
        if (StringUtils.isBlank(domain)) {
            return false;
        }
        domain = domain.replace("[", "");
        domain = domain.replace("]", "");
        String[] listStr = domain.split(",");
        String min = StringUtils.isBlank(listStr[0]) ? "-999" : listStr[0];  //2018.12.11修改，扩大输入值范围
        String max = StringUtils.isBlank(listStr[1]) ? "9999999" : listStr[1];
        if ((Double) val >= Double.valueOf(min) && (Double) val <= Double.valueOf(max)) {

        } else {
            return false;
        }
        return true;
    }

    @Override
    public ResMessage addXlsx(String projectCode, String id, InputStream is) throws BizException {

        RuleTest batchTest = this.get(id);


        String uploadRoot = Global.getConfig("file.uploadRoot");
        String uploadPath = uploadRoot + "/" + projectCode + batchTest.getBaseUpdatePath();

        String tempPath = uploadPath + File.separator + batchTest.getId() + ExcelConstant.EXCLE_SUFFIX;
        File f = new File(uploadPath);
        // 创建文件夹
        if (!f.exists()) {
            f.mkdirs();
        }
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(tempPath);
            byte[] b = new byte[1024];
            while (is.read(b) != -1) {
                fos.write(b);
            }

        } catch (Exception e) {
            LoggerManager.error("", e, this.getClass());
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {

                    e.printStackTrace();
                    throw new BizException(e, "E-005001");
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {

                    e.printStackTrace();
                    throw new BizException(e, "E-005001");
                }
            }
        }


        return updateBatchTest(batchTest);
    }


    private ResMessage updateBatchTest(RuleTest ruleTest) {
        ResMessage res = new ResMessage("success", "上传成功！");
        ruleTest.setStatus("10");
        this.save(ruleTest);

        return res;
    }

    /**
     * 测试Excel，并写入结果内容
     *
     * @param projectCode 项目编号
     * @param id          测试id
     */
    
    
    @SuppressWarnings("unchecked")
    @Override
    public void testExcel(String projectCode, String id) throws BizException {
        RuleTest ruleTest = this.get(id);

        String uploadRoot = Global.getConfig("file.uploadRoot");
        String uploadPath = uploadRoot + "/" + projectCode + ruleTest.getBaseUpdatePath();

        String tempPath = uploadPath + File.separator + ruleTest.getId() + ExcelConstant.EXCLE_SUFFIX;

        String filePathx = uploadPath + File.separator + ruleTest.getId() + ".xlsx";
        File file = new File(tempPath);
        File filex = new File(filePathx);

        String thepath = "";
        Long lastmodified = 0l;
        if (file.exists()) {
            lastmodified = file.lastModified();
        }
        Long lastmodifiedx = 0l;
        if (filex.exists()) {
            lastmodifiedx = filex.lastModified();
        }
        if (lastmodifiedx > lastmodified) {
            thepath = filePathx;
        }
        if (lastmodifiedx < lastmodified) {
            thepath = tempPath;
        }
		Workbook wb = null;
		FileInputStream readfout = null;
		try {
		    readfout = new FileInputStream(thepath);
		    if (thepath.endsWith(".xlsx")) {
            	wb = new XSSFWorkbook(readfout);
            } else {
                wb = new HSSFWorkbook(new POIFSFileSystem(readfout));
            }
		    readfout.close();
		} catch (Exception e) {}
		
		RuleReferenceData inputRefeData = new RuleReferenceData();
		inputRefeData.setCode(ruleTest.getModelCode());
		inputRefeData.setVersion(ruleTest.getVersion());
		inputRefeData.setContentType(ContentTypeEnum.in.code);
		inputRefeData.setModelType(ruleTest.getModelType());
		inputRefeData.setProjectCode(projectCode);
		List<RuleDataModelVO> inputList = this.findReferenceData(inputRefeData);
		
		RuleReferenceData outputRefeData = new RuleReferenceData();
		outputRefeData.setCode(ruleTest.getModelCode());
		outputRefeData.setVersion(ruleTest.getVersion());
		outputRefeData.setModelType(ruleTest.getModelType());
		outputRefeData.setContentType(ContentTypeEnum.out.code);
		outputRefeData.setProjectCode(projectCode);
		List<RuleDataModelVO> outputList = this.findReferenceData(outputRefeData);

        if (outputList == null || outputList.size() == 0) {
            throw new BizException("");
        }
        RuleReferenceData refeData = null;
        Map<String,RuleReferenceData> refeMap =null;
        for (RuleDataModelVO refData:outputList) {
        	refeMap = new HashMap<>();
         	for (int j =0;j<refData.getAttrList().size();j++) {
         		refeData = refData.getAttrList().get(j);
         		if (!refeMap.containsKey(refeData.getNameen())) {
         			refeMap.put(refeData.getNameen(), refeData);
         		}else if (ContentTypeEnum.out.code.equals(refeData.getContentType())){
         			refeMap.put(refeData.getNameen(), refeData);
         		}
         	}
         	refData.setAttrList(new ArrayList<>(refeMap.values()));
         }
	     Map<String, RuleReferenceData> paramMap = new HashMap<>();
	     for (RuleDataModelVO ruleDataModelVO : outputList) {
	        	for(RuleReferenceData ref:ruleDataModelVO.getAttrList()) {
	        		paramMap.put(ruleDataModelVO.getClassName()+ref.getNameen(),ref);
	        	}
		}
        
        int icount = wb.getNumberOfSheets();
        for (int k =0;k<icount;k++) {
		        Sheet sheet = wb.getSheetAt(k);
		        if (isExcSheetEmpty(sheet)) {
		        	continue;
		        }
		        JSONObject json = new JSONObject();
		        List<Object> toplist = new ArrayList<Object>();
		        List<Object> list = new ArrayList<Object>();
		        List<Object> list2 = new ArrayList<Object>();
		        List<Object> list3 = new ArrayList<Object>();
		        json.put(ExcelConstant.R, toplist);
		        json.put(ExcelConstant.R1, list);
		        json.put(ExcelConstant.R2, list2);
		        json.put(ExcelConstant.R3, list3);
		
		        toplist.add(ExcelConstant.TESTTIME_CELL + spf.format(new Date()));
		        // 写入xml结果头部
		  	    this.writeExcelHeader(wb, outputList, paramMap, list3, list2, list, json, sheet);
		        // 数据获取			
		        List<Map<String, Object>> resultMaps = getInputMap(sheet, inputList, outputList, projectCode);
		
		        RuleTestMap ruleTestMap = new RuleTestMap();
		        ruleTestMap.setProjectCode(projectCode);
		        ruleTestMap.setCode(ruleTest.getModelCode());
		        ruleTestMap.setType(ruleTest.getModelType());
		        ruleTestMap.setVersion(ruleTest.getVersion());

		        RuleBatchResult  ruleBatchResult = this.ruleTestService.testBatchRule(ruleTestMap, resultMaps);
		        writeExcuteTime(wb.createCellStyle(),sheet,ruleBatchResult.getExecuteDateTime());
		        Map<String, List<Object>> rusultMaps = new HashMap<String, List<Object>>();
		        for (Map<String, Object> input : resultMaps) {
		            toRusultList(input, rusultMaps);
		        }
		        Map<String, List<RuleDataDomain>> getThendmsDomain = getThendmsDomain(outputList);
		        this.writeExcleRusult(sheet, rusultMaps, outputList, getThendmsDomain);
		        //writeSingleExcuteTime(wb.createCellStyle(),sheet,ruleBatchResult.getRuleSingleTest().getExecTime());
        }
        this.createExcelFile(wb, ruleTest);
        ruleTest.setStatus("11");//
        this.save(ruleTest);


    }
    
    
    
    private   void    writeExcuteTime(CellStyle style,Sheet sheet,Long executeDateTime) {
    	  Row  row  = sheet.getRow(0);
    	  int  lastCellNum = row.getLastCellNum()+1;
    	  Cell cell =row.createCell(lastCellNum);
    	  style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
    	  style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
    	  style.setAlignment(CellStyle.ALIGN_CENTER);
    	  cell.setCellStyle(style);
    	  cell.setCellValue("总执行时间："+executeDateTime);
    	
    }
    
    private  void   writeSingleExcuteTime(CellStyle style,Sheet sheet,List<Object> tList) {
    	  Row  row  = sheet.getRow(3);
	  	  int  lastCellNum = row.getLastCellNum()+1;
	  	  Cell cell =row.createCell(lastCellNum);
	  	  style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
	  	  style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
	  	  style.setAlignment(CellStyle.ALIGN_CENTER);
	  	  cell.setCellStyle(style);
	  	  cell.setCellValue("执行时间");
	  	  Row  tRow = null; 
	  	  Cell  tCell = null;
	  	  for (int i=0;i<tList.size();i++) {
	  		   tRow  =  sheet.getRow(i+4);
	  		   tCell = tRow.createCell(tRow.getLastCellNum()+1);
	  		   tCell.setCellValue(""+tList.get(i).toString()+"");
	  	  }
    	
    }
    
    private   boolean   isExcSheetEmpty(Sheet sheet) {
    	   boolean  flag  =false;
    	   Row row = sheet.getRow(1);
    	   int  irow =row.getLastCellNum();
    	   if (irow <2) {
    		   return  true;
    	   }
    	   return  flag;
    	   
    }
    
    public   void   createExcelFile(Workbook wb,RuleTest  ruleTest) {
        String resultBasePath = Global.getConfig("file.uploadRoot") + File.separator + ruleTest.getProjectCode() + ruleTest.getResultPath();
        File f = new File(resultBasePath);
        // 创建文件夹
        if (!f.exists()) {
            f.mkdirs();
        }
        String resultExcleFile = resultBasePath + File.separator + ruleTest.getId() +".xlsx";
        try { 
            FileOutputStream fout = new FileOutputStream(resultExcleFile);
            wb.write(fout);
            fout.close();
        } catch (Exception e) {
            LoggerManager.error("", e, this.getClass());
        }finally {
        	try {
				wb.close();
			} catch (IOException e) {
				e.printStackTrace();
			}

        }
    }
    
    
    public   void   writeExcelHeader(Workbook wb, List<RuleDataModelVO> dataList,Map<String, RuleReferenceData> paramMap,
    		List<Object> list3,List<Object> list2, List<Object> list,JSONObject json,Sheet sheet ) {
	    	CellStyle style = wb.createCellStyle();
	        style.setAlignment(CellStyle.ALIGN_CENTER);	
	        int countAttr = 0;
	        for (RuleDataModelVO dm : dataList) {
	            if (dm.getAttrList().size() > 0 && dm.getAttrList().get(0) != null) {
	            	int size = 0;
	                for (Entry<String ,RuleReferenceData> entry : paramMap.entrySet()) {
	                	if(!dm.getClassName().equals(entry.getValue().getClassName())) 
	                		continue;
	                	if(list3.contains(entry.getValue().getClassNamecn()+"."+entry.getValue().getNamecn()))
	                		continue;
	                	list3.add(entry.getValue().getClassNamecn()+"."+entry.getValue().getNamecn());
	                	countAttr++;
	                    size++;
	        		}
	                list2.add(dm.getClassNamecn() + "##" + size);
	            }
	        }
	        if (countAttr > 1) {
	            list.add(ExcelConstant.RESULT_CELL + "##" + countAttr);
	        } else {
	            list.add(ExcelConstant.RESULT_CELL);
	        }
	        // 删除结果
	        int result_col = isResult(sheet);
	        if (result_col > 0) {
	            removeTestTimeCell(sheet);
	            for (int i = 1; (i < ExcelConstant.ROW_VALIDATION_NUM) && (i <= sheet.getLastRowNum()); i++) {
	                for (int j = result_col; j < sheet.getRow(i).getLastCellNum(); j++) {
	                    sheet.getRow(i).removeCell(sheet.getRow(i).getCell(j));
	                }
	            }
	        }
	        writeRusultHeadText(json.getJSONArray(ExcelConstant.R), style, sheet.getRow(0), sheet);
	        CellStyle cellStyle = wb.createCellStyle();
	        // 设置这些样式
	        cellStyle.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
	        cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
	        cellStyle.setAlignment(CellStyle.ALIGN_CENTER);
	        writeRusultHeadText(json.getJSONArray(ExcelConstant.R1), cellStyle, sheet.getRow(1), sheet);
	        writeRusultHeadText(json.getJSONArray(ExcelConstant.R2), style, sheet.getRow(2), sheet);
	        writeRusultHeadText(json.getJSONArray(ExcelConstant.R3), style, sheet.getRow(3), sheet);

    }
    

    // 是否存在结果
    private int isResult(Sheet sheet) {
        Row row = sheet.getRow(1);
        for (int i = 1; i < row.getLastCellNum(); i++) {
            if (row.getCell(i).getStringCellValue().equals(ExcelConstant.RESULT_CELL)) {
                return i;
            }
        }
        return 0;
    }


    public static void writeRusultHeadText(List<Object> getList, CellStyle style, Row row, Sheet sheet) {
        int preLength = 0;
        int k = 0;
        int lastCellNum = row.getLastCellNum();
        for (int i = lastCellNum; i < lastCellNum + getList.size(); i++) {
            Cell cell = row.createCell((short) i + preLength);
            k = i - lastCellNum;
            cell.setCellValue(getValue(getList.get(k).toString()));
            int lastColIndex = cell.getColumnIndex() + Integer.valueOf(getColSpan(getList.get(k).toString())) - 1;
            cell.setCellStyle(style);
            if ((cell.getColumnIndex()) < lastColIndex)
                sheet.addMergedRegion(new CellRangeAddress(cell.getRowIndex(), cell.getRowIndex(), cell.getColumnIndex(), lastColIndex));
            preLength = preLength + Integer.valueOf(getColSpan(getList.get(k).toString())) - 1;
        }
    }


    // 删除测试
    private void removeTestTimeCell(Sheet sheet) {
        Row row = sheet.getRow(0);
        for (int i = 1; i < row.getLastCellNum(); i++) {
            if (row.getCell(i).getStringCellValue().indexOf(ExcelConstant.TESTTIME_CELL) >= 0) {
                row.removeCell(row.getCell(i));
            }
        }
    }

    private List<Map<String, Object>> getInputMap(Sheet sheet, List<RuleDataModelVO> dms, List<RuleDataModelVO> thendms, String projectCode) throws BizException {
        Map<String, List<Object>> inputXmls = getInputXml(sheet);
        List<Map<String, Object>> inputMaps = new ArrayList<Map<String, Object>>();
        Map<String, MClass> metaMap = this.dataBomService.findMapClass(projectCode);
        Map<String,List<String>>  tmap  = new  HashMap<>();
        List<String> reList  =null;
        for  ( RuleDataModelVO rmv:thendms) {
        	 for (RuleReferenceData rfd: rmv.getAttrList()) {
                 reList = tmap.get(rfd.getClassName());
                 if (reList == null) {
                	 reList  = new  ArrayList<>();
                 }	 
                 reList.add(rfd.getNameen());
        		 tmap.put(rfd.getClassName(),reList );
        	 }
        }
        for (RuleDataModelVO dm:dms) {
        	for(RuleReferenceData rdm:dm.getAttrList()) {
        		   reList = tmap.get(rdm.getClassName());
                   if (reList == null) {
                  	 reList  = new  ArrayList<>();
                   }	 
                   reList.add(rdm.getNameen());
          		   tmap.put(rdm.getClassName(),reList );
        	}
        }
        for (int i = 0; (i < ExcelConstant.ROW_VALIDATION_NUM) && (i <= sheet.getLastRowNum() - 4); i++) {
            Map<String, Object> inputMap = new HashMap<String, Object>();
            boolean flag = true;
            for(String className:metaMap.keySet()) {
            	Map<String, Object> supinputMap = new HashMap<String, Object>();
        		MClass mclass = metaMap.get(className);
    			Map<String,MField> fieldMap = mclass.getFieldMap();
    			for(String name:fieldMap.keySet()) {
    				MField mField = fieldMap.get(name);
    				String dmpkey = mclass.getChzn()+"."+mField.getChzn();
                    if (inputXmls.containsKey(dmpkey)) {
                        flag = flag || inputXmls.get(dmpkey).get(i) != null || !inputXmls.get(dmpkey).get(i).equals("");

                        if (!mField.getType().equals(Constant.DATAMODEL_ATTRIBUTE_TYPE_STRING) && inputXmls.get(dmpkey).size()>i && inputXmls.get(dmpkey).get(i).toString().equals("")) {
                        		 //supinputMap.put(attr.getNameen(), null);	
                        		 			
                        } else if (mField.getType().equals(Constant.DATAMODEL_ATTRIBUTE_TYPE_LONG)) {
                        	if( inputXmls.get(dmpkey).size()<=i) {  //by yangpingxia 2018.120,当List中存在空值，令key对应的value值，保持空值。继续执行，无需报错。
                        		 supinputMap.put(name, null);	
                        	}else {
                        		if (inputXmls.get(dmpkey).get(i) !=null) {
                        			supinputMap.put(name, Math.round(Double.parseDouble(inputXmls.get(dmpkey).get(i).toString())));
                        		}else {
                        			supinputMap.put(name, null);	
                        		}
                        		
                        	}
                        } else if (StringUtils.isNotBlank(mField.getDomainStr())) {  
                            // 转义
                            List<RuleDataDomain> domainList = this.dataBomService.findDataDomains(mField.getDomain());

                            for (RuleDataDomain item : domainList) {
                                if (inputXmls.get(dmpkey).size()>i && item.getName().equals(inputXmls.get(dmpkey).get(i))) {
                                    supinputMap.put(name, item.getDomainValue());
                                    break;
                                }
                            }
                        } else if(inputXmls.get(dmpkey).size()>i){
                            supinputMap.put(name, inputXmls.get(dmpkey).get(i));
                        }
                    }
                   
    			}
    			List<String> rrList  =  tmap.get(className);
    			if (rrList != null) {
    				for (String  paramEn :rrList) {
    					if (!supinputMap.containsKey(paramEn)) {
    						supinputMap.put(paramEn, null);
    					}
    				}
    			}
    			inputMap.put(className, supinputMap);
        	}
             
            
            if (flag)
                inputMaps.add(inputMap);
    		
        }

        return inputMaps;
    }


    
    @Override
    public void delBatchTest(String id, String projectCode) throws BizException {
        RuleTest ruleTest = this.get(id);
        String uploadRoot = Global.getConfig("file.uploadRoot");
        //上传文件
        String perixFile = uploadRoot + File.separator + projectCode + ruleTest.getBaseUpdatePath() + File.separator + ruleTest.getId();
        String uploadFile = perixFile + ".xls";
        File file = new File(uploadFile);
        if (file.exists()) {
            file.delete();
        }
        uploadFile = perixFile + ".xlsx";
        file = new File(uploadFile);
        if (file.exists()) {
            file.delete();
        }
        //结果文件
        String resultFile = uploadRoot + File.separator + projectCode + ruleTest.getResultPath() + File.separator + ruleTest.getId() + ".xlsx";
        File rFile = new File(resultFile);
        if (rFile.exists()) {
            rFile.delete();
        }
        this.delete(ruleTest);

    }
    
    @SuppressWarnings("unchecked")
    private void toRusultList(Map<String, Object> input, Map<String, List<Object>> rusultMaps) {
        for (Map.Entry<String, Object> inputEntry : input.entrySet()) {
            if (inputEntry.getKey().equals("tracks")) {
                continue;
            }
            Map<String, Object> temp = new HashMap<String, Object>();
            temp = (Map<String, Object>) inputEntry.getValue();
            for (Map.Entry<String, Object> entry : temp.entrySet()) {
                List<Object> rsultList = new ArrayList<Object>();
                if (rusultMaps.get(inputEntry.getKey()+"."+entry.getKey()) == null) {
                    rusultMaps.put(inputEntry.getKey()+"."+entry.getKey(), rsultList);
                } else {
                    rsultList = rusultMaps.get(inputEntry.getKey()+"."+entry.getKey());
                }
                if(rsultList==null)
                	rsultList = new ArrayList<Object>();
                rsultList.add(entry.getValue());
            }
        }
    }

    private Map<String, List<RuleDataDomain>> getThendmsDomain(List<RuleDataModelVO> thendms) throws BizException {
        Map<String, List<RuleDataDomain>> getThendmsDomain = new HashMap<String, List<RuleDataDomain>>();
        List<RuleDataDomain> list = null;
        for (RuleDataModelVO dm : thendms) {
            for (RuleReferenceData attr : dm.getAttrList()) {
                if (attr == null) {
                    break;
                }
                if (attr.getDomain() != null) {
                    list = this.dataBomService.findDataDomains(attr.getDomain());
                    if (list != null && list.size() > 0)
                        getThendmsDomain.put(attr.getNameen(), list);
                }
            }
        }
        return getThendmsDomain;
    }
    
    private void writeExcleRusult(Sheet sheet, Map<String, List<Object>> rusultMaps, List<RuleDataModelVO> thendms, Map<String, List<RuleDataDomain>> getThendmsDomain) {
        List<RuleReferenceData> tmpList = new ArrayList<>();
        for (RuleDataModelVO dataModelVO : thendms) {
            tmpList.addAll(dataModelVO.getAttrList());
        }
        Map<String, String> atrrNameZhcnMap = AtrrNameZhcnMap(tmpList);
        Row row = sheet.getRow(3);
        for (int i = 1; i < row.getLastCellNum(); i++) {
            String getStringCellValue = row.getCell(i).getStringCellValue().toString();
            for (Map.Entry<String, String> entry : atrrNameZhcnMap.entrySet()) {
                if (!entry.getValue().equals(getStringCellValue)) {
                    continue;
                }
                if (rusultMaps.get(entry.getKey()) != null) {
                	int k =4;
                	
                    for (Object val : rusultMaps.get(entry.getKey())) {
                    	//k++;
                        Row r = sheet.getRow(k);

                        Cell cell = r.createCell((short) i);
                        String valString = "";
                        if (val != null) {
                            valString = val.toString();
                        }
                        if (getThendmsDomain.get(entry.getKey()) != null) {
                            List<RuleDataDomain> itmes = getThendmsDomain.get(entry.getKey());
                            for (RuleDataDomain item : itmes) {
                                if (item.getDomainValue().equals(valString)) {
                                    valString = item.getName();
                                    break;
                                }
                            }
                        }
                        cell.setCellValue(valString);
                        k++;
                    }
                }
            }
        }
    }   


    //多线程
    class SubTask extends RecursiveAction {

        private static final long serialVersionUID = 1L;

        private Map<String, List<Object>> inputMaps;
        private int beg;
        private int end;
        private String type;

        Sheet sheet;

        List<RuleDataModelVO> dataModelList;
        Map<String, List<RuleDataDomain>> getThendmsDomain;

        public SubTask(Map<String, List<Object>> inputMaps, int beg, int end, String type, Sheet sheet, List<RuleDataModelVO> dataModelList, Map<String, List<RuleDataDomain>> getThendmsDomain) {
            super();
            this.inputMaps = inputMaps;
            this.beg = beg;
            this.end = end;
            this.type = type;

            this.sheet = sheet;
            this.dataModelList = dataModelList;
            this.getThendmsDomain = getThendmsDomain;
        }


        @Override
        protected void compute() {
            if (end - beg > ExcelConstant.EXR_DROOL_EXR_RPE_SIZE) {
                int mid = (beg + end) / 2;
                if (sheet != null) {
                    SubTask t1 = new SubTask(inputMaps, beg, mid, type, sheet, this.dataModelList, getThendmsDomain);
                    SubTask t2 = new SubTask(inputMaps, mid, end, type, sheet, this.dataModelList, getThendmsDomain);
                    invokeAll(t1, t2);
                }

            } else {
                try {
                    if (sheet != null) {
                        writeRusult(sheet, inputMaps, this.dataModelList, getThendmsDomain, beg, end);
                    }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    //e.printStackTrace();
                    LoggerManager.error("", e, this.getClass());
                }
            }
        }
    }

    private void writeRusult(Sheet sheet, Map<String, List<Object>> rusultMaps, List<RuleDataModelVO> thendms, Map<String, List<RuleDataDomain>> getThendmsDomain, int beg, int end) {
        List<RuleReferenceData> tmpList = new ArrayList();
        for (RuleDataModelVO dataModelVO : thendms) {
            tmpList.addAll(dataModelVO.getAttrList());
        }
        Map<String, String> atrrNameZhcnMap = AtrrNameZhcnMap(tmpList);
        Row row = sheet.getRow(3);
        for (int i = 1; i < row.getLastCellNum(); i++) {
            String getStringCellValue = row.getCell(i).getStringCellValue().toString();
            for (Map.Entry<String, String> entry : atrrNameZhcnMap.entrySet()) {
                if (!entry.getValue().equals(getStringCellValue)) {
                    continue;
                }
                int k = 4 + beg;
                if (rusultMaps.get(entry.getKey()) != null) {
                    for (Object val : (rusultMaps.get(entry.getKey()).subList(beg, end))) {
                        Row r = sheet.getRow(k);

                        Cell cell = r.createCell((short) i);
                        String valString = "";
                        if (val != null) {
                            valString = val.toString();
                        }
                        if (getThendmsDomain.get(entry.getKey()) != null) {
                            List<RuleDataDomain> itmes = getThendmsDomain.get(entry.getKey());
                            for (RuleDataDomain item : itmes) {
                                if (item.getDomainValue().equals(valString)) {
                                    valString = item.getName();
                                    break;
                                }
                            }
                        }
                        cell.setCellValue(valString);
                        if (k >= end + 4) {
                            break;
                        }
                        k++;
                    }
                }
            }
        }

    }


}
